package com.restaurant.springboot.service.impl;

import com.restaurant.springboot.entity.DishesEntity;
import com.restaurant.springboot.entity.OrderEntity;
import com.restaurant.springboot.entity.OrderItemEntity;
import com.restaurant.springboot.repositories.DishesRepository;
import com.restaurant.springboot.repositories.OrderItemRepository;
import com.restaurant.springboot.repositories.OrderRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @Author jack
 * @Date:2019/7/30 11:21
 */
@Service
public class OrderServiceImpl implements com.restaurant.springboot.service.OrderService {

    @Autowired
    OrderRepository orderRepository;

    @Autowired
    OrderItemRepository orderItemRepository;

    @Autowired
    DishesRepository dishesRepository;

    enum OrderState {
        CREATE(0),
        HANDLING(1),
        FINISHED(2),
        CANCEL(3),
        COMMENTED(4);
        private int index;

        OrderState(int index) {
            this.index = index;
        }

        public int getIndex() {
            return index;
        }
    }

    @Override
    public List<OrderEntity> getAllOrder() {
        return orderRepository.findAll();
    }

    @Override
    public List<OrderEntity> getAllOrderForUser(int userId) {
        return orderRepository.findALLByUserId(userId);
    }

    @Override
    public OrderEntity createOrder(OrderEntity orderEntity) {
        orderEntity.setState(OrderState.CREATE.getIndex());
        return orderRepository.save(orderEntity);
    }

    /**
     * 取消订单
     *
     * @param orderEntity 订单实体
     * @return 操作是否成功（仅判断是否存在这个对象）
     */
    @Override
    public boolean cancelOrder(OrderEntity orderEntity) {
        return changeOrderState(orderEntity, OrderState.CANCEL);
    }

    /**
     * 状态机图如下
     * CREATE -> HANDING ->FINISHED(结束状态)
     * |
     * |----> CANCEL(结束状态)------->COMMENT
     *
     * @param orderEntity 订单实体
     * @param orderState  订单新状态
     * @return 操作结果
     */
    private boolean changeOrderState(OrderEntity orderEntity, OrderState orderState) {
        if (orderEntity == null) {
            return false;
        } else {
            int originState = orderEntity.getState();
            int nextState = orderState.getIndex();
            if (originState == 0) {
                if (!(nextState == 1 || nextState == 3)) { // (
                    return false;
                }
            } else if (originState == 1) {
                if (nextState != 2) {
                    return false;
                }
            } else if (originState == 2 || originState == 3|| originState == 4) {
                return false;
            }
            orderEntity.setState(nextState);
            orderRepository.save(orderEntity);
            return true;
        }
    }

    @Override
    public OrderEntity getOrderById(Integer id) {
        Optional<OrderEntity> byId = orderRepository.findById(id);
        if (!byId.isPresent()) {
            return null;
        } else {
            return byId.get();
        }
    }

    @Override
    public boolean finishOrder(OrderEntity orderEntity) {
        return changeOrderState(orderEntity, OrderState.FINISHED);
    }

    @Override
    public boolean handlingOrder(OrderEntity orderEntity) {
        return changeOrderState(orderEntity, OrderState.HANDLING);
    }

    @Override
    public boolean createOrderItem(OrderItemEntity orderItemEntity) {
        if (orderItemEntity == null) {
            return false;
        } else {
            //check int
            Optional<DishesEntity> byId = dishesRepository.findById(orderItemEntity.getDishesId());
            if (!byId.isPresent()) {
                return false;
            }
            DishesEntity dishesEntity = byId.get();
            orderItemEntity.setPrice(dishesEntity.getPrice());
            orderItemRepository.save(orderItemEntity);
            return true;
        }
    }

    @Override
    public Page<OrderEntity> getAllOrder(int page, int pageLen) {
        Pageable pageable = PageRequest.of(page - 1 , pageLen);
        return orderRepository.findAll(pageable);
    }

    @Override
    public Page<OrderEntity> getAllOrderForUser(int page, int pageLen, int userId) {
        Pageable pageable = PageRequest.of(page-1, pageLen);
        return orderRepository.findALLByUserId(pageable, userId);
    }

    @Override
    public OrderEntity updateOrder(OrderEntity orderEntity) {
       return  orderRepository.save(orderEntity);
    }

    @Override
    public boolean isExistsOrder(int orderId) {
        return orderRepository.existsById(orderId);
    }

    @Override
    public Page<OrderEntity> getAllOrder(int page, int pageLen, Date startTime, Date endTime) {
        Pageable pageable = PageRequest.of(page-1, pageLen);
        return orderRepository.findAllByCreateTimeBetween(pageable, startTime, endTime);
    }




}
